home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / misc / emu / ATUtilities.lha / ATUtilities / ASM / RAMDRIVE.ASM < prev    next >
Assembly Source File  |  2000-09-26  |  29KB  |  722 lines

  1. Page ,132
  2. title   RDISK.ASM - Virtuelles Laufwerk
  3. ;**********************************************************;
  4. ; RDISK.ASM  RAM-Disk fr Expanded Memory / Hauptspeicher. ;
  5. ;   Version: 1.1                                           ;
  6. ;   Sprache: Microsoft MASM 4.0 oder h”her                 ;
  7. ;     Autor: M. Greve                                      ;
  8. ;šbersetzen: MASM /ML RDISK;                               ;
  9. ;            LINK RDISK;                                   ;
  10. ;            EXE2BIN RDISK.EXE RDISK.SYS                   ;
  11. ; Anwendung: DEVICE=RDISK.SYS [xxx] [/A]                   ;
  12. ;**********************************************************;
  13.  
  14. ;-----( Befehle des EMM-Interrupts 67h )--------------------
  15. EMM         =     67h           ;Interrupt
  16. EMMframe    =     41h           ;Segment-Adr. des EMM
  17. EMMfree     =     42h           ;Freie Seiten ermitteln
  18. EMMalloc    =     43h           ;EMM-Seiten zuteilen
  19. EMMmapp     =     44h           ;Seite ins Fenster laden
  20. EMMsave     =     47h           ;EMM-Zustand sichern
  21. EMMreset    =     48h           ;EMM-Zugriff zulassen
  22.  
  23. ;-----( Status-Codes )--------------------------------------
  24. CMD_ERR     =   8103h           ;Ungltiger Befehl
  25. CRC_ERR     =   8104h           ;CRC-Fehler
  26. SEC_ERR     =   8108h           ;Ungltiger Sektor
  27. GEN_ERR     =   810Ch           ;Undefinierter Fehler
  28. SZ_ERR      = 00000001b         ;Ungengend Speicher
  29. NoEMM_ERR   = 00000100b         ;Kein Expanded Speicher
  30. EMM_ERR     = 00001000b         ;Exp. Speicher Fehler
  31. OPT_ERR     = 00010000b         ;Ungltige Option
  32.  
  33. ;-----( Allg. Konstanten )----------------------------------
  34. MEDIA_ID    =    0F8h           ;Media Descriptor Byte
  35. MAXFAT      =   0FF7h           ;Max. Anzahl FAT-Eintr„ge
  36. EXPANDED    =      1            ;Expanded Speicher-Flag
  37. MIN_MEM     =     64            ;Min. freier Speicher
  38. MIN_REQ     =     16            ;kleinstm”gliche RamDisk
  39. SECSZ       =    512            ;Byte / Sektor
  40. DFLTSZ      =    128            ;Default Diskgr”áe (64kB)
  41. MAXCMD      =     12            ;Max. zugelassener Befehl
  42. READCMD     =      4            ;Nummer des Lesebefehls
  43. CR          =     0Dh
  44. LF          =     0Ah
  45. BEEP        =      7
  46.  
  47. ;-----( Request-Header-Strukturen )-------------------------
  48. RH          equ ES:[DI] ;Zugriffszeiger fr Request-Header
  49. RHx STRUC               ;Gemeinsame Felder im Reqest-Header
  50.             db  ?               ;L„nge d. Req.-Header
  51.             db  ?               ;Ger„te-(Einheit)-Nummer
  52. CMDcode     db  ?               ;Befehls-Code
  53. CMDstat     dw  ?               ;Statuswort
  54.             dq  ?               ;Reserviert fr DOS
  55. RHx ENDS
  56. RH0 STRUC  ;Fn.0:Init;  Fn.1:Media Check;  Fn.2: Build-BPB
  57.             db  (TYPE RHx) DUP (?)  ; gemeinsamer Teil
  58. Unum        db  ?               ;Anzahl inst. Ger„te
  59. EndOfs      dw  ?               ;Ende des Treibers, Offs
  60. EndSeg      dw  ?               ;Ende des Treibers, Segm
  61. BPBofs      dw  ?               ;BPB Tabelle, Offset
  62. BPBseg      dw  ?               ;BPB Tabelle, Segment
  63. DrvCode     db  ?               ;Laufw.-Code ab DOS 3.xx
  64. RH0 ENDS
  65. MediaCh     equ byte ptr EndOfs ;"Media Change" Flag
  66. BPBadr      equ dword ptr BPBofs;32Bit Adresse des BPB
  67.  
  68. ;Beim Aufruf von "Init" zeigt BPBofs auf "DEVICE=" Zeile.
  69. ConfigLn    equ dword ptr BPBofs
  70. RH4 STRUC  ;Fn.4:Read;   Fn.8:Write;   Fn.9:Write/Verify
  71.             db  (TYPE RHx) DUP (?)  ;gemeinsamer Teil
  72.             db  ?               ;Media Descriptor Byte
  73. DTAadr      dd  ?               ;DTA adresse (32Bit)
  74. SecCnt      dw  ?               ;Sektorenz„hler
  75. StrtSec     dw  ?               ;Erster Sektor
  76. RH4 ENDS
  77.  
  78. ;-----( Text-Ausgabe-Makro )--------------------------------
  79. @Print MACRO Text
  80.         push    DX
  81.         lea     DX,Text
  82.         mov     AH,9
  83.         int     21h
  84.         pop     DX
  85. ENDM
  86.  
  87. ;-----( Programmbeginn )------------------------------------
  88. CODE    SEGMENT para public
  89.         ASSUME  CS:CODE, DS:CODE
  90.         ORG 0
  91. Main:
  92. ;-----( Ger„tetreiberkopf )---------------------------------
  93. DvcHdr      dd  -1              ;Zeiger auf n„chsten Treiber
  94.             dw  0800h           ;Block-Treiber-Attribut
  95.             dw  Strategy        ;Strategy Routine
  96.             dw  DVCintrpt       ;Interrupt-Routine
  97.             db  'RAMD 1.0'      ;Treibername (8Byte)
  98. ReqHdr      dd  ?               ;Request-Header-Adresse
  99.  
  100. ;-----( Funktionstabelle )----------------------------------
  101. ; Alle Funktionen werden ber die Adresse ES:Dispatch[BX]
  102. ; aufgerufen und kehren mit dem Fehlercode im AX-Register
  103. ; zu DOS zurck.
  104. ;-----------------------------------------------------------
  105. Dispatch    dw  Init            ; 0 - Initialisierung
  106.             dw  MedChk          ; 1 - Diskettenwechsel
  107.             dw  BldBPB          ; 2 - BPB aufbauen
  108.             dw  Exit            ; 3 - I/O Ctrl Ein
  109.             dw  Read            ; 4 - Block lesen
  110.             dw  Exit            ; 5 - Zeichen lesen
  111.             dw  Exit            ; 6 - Eing. Status
  112.             dw  Exit            ; 7 - Eingabe l”schen
  113.             dw  Write           ; 8 - Block schreiben
  114.             dw  Write           ; 9 - Schreiben mit Verify
  115.             dw  Exit            ;10 - Ausgabe Status
  116.             dw  Exit            ;11 - Ausgabe l”schen
  117.             dw  Exit            ;12 - I/O Control Aus
  118.  
  119. ;-----( Datenbereich )--------------------------------------
  120. Progname    db  CR,LF,'RDISK.SYS - (c) 1990  '
  121.             db  'c''t / M. H. Grev‚',CR,LF,'$'
  122. EVEN                            ;gerade Adresse fr Stack!
  123.             db  32 dup ('stak') ;programminterner Stack
  124. Stak:                           ;Stack-Kopf
  125. oldSP       dw  ?               ;alter Stack-Pointer
  126. oldSS       dw  ?
  127. oldAX       dw  ?               ;Ablage fr AX-Register
  128. Cmd         db  ?               ;aktueller Befehl
  129. MemTyp      db  0               ;0 = Hauptspeicher
  130.                                 ;1 = Expanded Speicher
  131. Npages      dw  DFLTSZ/16       ;Diskgr”áe in EMM-Seiten
  132. FrameSeg    dw  ?               ;Segment des EMM-Fensters
  133. XfrSec      dw  ?               ;Sektor
  134. XfrCnt      dw  ?               ;Sektorenz„hler
  135. XfrAdr      label dword         ;lokale Kopie der
  136. XfrAdrO     dw  ?               ;DTA-Adresse
  137. XfrAdrS     dw  ?
  138. EMMhdl      dw  ?               ;EMM-Handle
  139. LastPge     dw -1               ;Zuletzt verw. EMM-Seite
  140.  
  141. ;-----( BIOS-Parameter-Block )------------------------------
  142. BPB         equ $
  143. SecSz       dw  SECSZ           ;Byte/Sektor
  144. ClstrSz     db  2               ;Sektoren/Cluster
  145. ResSecs     dw  1               ;Reserv. Sektoren
  146.             db  1               ;Anzahl FAT-Kopien
  147. NDir        dw  DFLTSZ/4        ;Eintr. im Root
  148. DiskSz      dw  DFLTSZ          ;Anzahl Sektoren
  149.             db  MEDIA_ID        ;Media descriptor
  150. FATsec      dw  2               ;Sektoren pro FAT
  151.             dw  8               ;Sektoren pro Spur
  152.             dw  1               ;Lesek”pfe
  153.             dw  0               ;Versteckte Sektoren
  154. BPBlen      equ $ - BPB         ;L„nge des BPB
  155. BPBptr      dw  offset BPB      ;Zeiger auf BPB
  156.  
  157. ;-----( Strategy )------------------------------------------
  158. ; Sichert Zeiger auf Request-Header
  159. ;-----------------------------------------------------------
  160. Strategy proc far
  161.         mov     word ptr CS:ReqHdr,BX
  162.         mov     word ptr CS:ReqHdr+2,ES
  163.         ret
  164. Strategy endp
  165.  
  166. ;-----( Ger„tetreiber-"Interrupt" )-------------------------
  167. DVCintrpt proc far
  168.         mov     CS:oldAX,AX     ;Wert von AX sichern
  169.         mov     CS:oldSP,SP     ;Alten Stack-Pointer sichern
  170.         mov     CS:oldSS,SS
  171.         mov     AX,CS
  172.         cli
  173.         mov     SS,AX           ;Eigenen Stack einrichten
  174.         mov     SP,offset Stak
  175.         sti
  176.         push    BX
  177.         push    CX
  178.         push    DX
  179.         push    DS
  180.         push    ES
  181.         push    DI
  182.         push    SI
  183.         push    BP
  184.         mov     DS,AX           ;DS-> Unsere Daten
  185.         les     DI,ReqHdr       ;ES:DI -> Request-Header
  186.         mov     BL,RH.CMDcode   ;BX = Befehls-Code
  187.         sub     BH,BH
  188.         cmp     BL,MAXCMD       ;Befehl gltig ?
  189.         mov     AX,CMD_ERR      ;Fehler-Code
  190.         ja      DVCend          ;Abbruch!
  191.         or      BX,BX           ;Initialisierung ?
  192.         jz      DVC1            ;Ja
  193.         test    MemTyp,EXPANDED ;EMM-Speicher ?
  194.         jz      DVC1            ;Nein
  195.         mov     AH,EMMsave      ;EMM-Speicherzustand sichern
  196.         mov     DX,EMMhdl
  197.         int     EMM
  198.         or      AH,AH
  199.         jnz     DVCerr
  200. DVC1:   add     BX,BX           ;BX = Befehlsindex
  201.         call    Dispatch[BX]    ;Aufruf des Befehls
  202.         les     DI,ReqHdr       ;ES:DI->Req. Header
  203.         test    MemTyp,EXPANDED
  204.         jz      DVCend
  205.         cmp     RH.CMDcode,0    ;Init. Befehl?
  206.         je      DVCend          ;Ja
  207.         push    AX              ;Statuswort sichern
  208.         mov     AH,EMMreset     ;EMM-Zugriff zulassen
  209.         mov     DX,EMMhdl
  210.         int     EMM
  211.         or      AH,AH           ;EMM-Fehler ?
  212.         pop     AX
  213.         jz      DVCend          ;Alles OK
  214. DVCerr: mov     AX,GEN_ERR      ;Fehler melden
  215. DVCend: mov     RH.CMDstat,AX   ;Status in Req. Hdr ablegen
  216.         pop     BP              ;Register zurcksetzen
  217.         pop     SI
  218.         pop     DI
  219.         pop     ES
  220.         pop     DS
  221.         pop     DX
  222.         pop     CX
  223.         pop     BX
  224.         cli
  225.         mov     SS,CS:oldSS
  226.         mov     SP,CS:oldSP     ;den Stack nicht vergessen !
  227.         sti
  228.         mov     AX,CS:oldAX
  229.         ret
  230. DVCintrpt endp
  231.  
  232. ;-----( Funktion 1: Media Check )---------------------------
  233. ; Ueberprft ob Diskette gewechselt wurde.
  234. ;-----------------------------------------------------------
  235. MedChk: mov     RH.MediaCh,1    ; nicht gewechselt
  236.         sub     AX,AX           ; (es ist ja eine RAM-Disk!)
  237.         ret
  238.  
  239. ;-----( Funktion 2: Build BPB )-----------------------------
  240. ; Adresse der BPB-Tabelle an DOS zurckgeben.
  241. ;-----------------------------------------------------------
  242. BldBPB: mov     RH.BPBofs,offset BPB
  243.         mov     RH.BPBseg,CS
  244.         sub     AX,AX
  245.         ret
  246.  
  247. ;-----( Funktionen 4, 8 und 9: Disk-Ein/Ausgabe )-----------
  248. Read:
  249. Write:  cld                     ;Richtungsflag l”schen
  250.         mov     LastPge,-1      ;Letzte EMM-Seite
  251.         mov     AL,RH.CMDcode
  252.         mov     Cmd,AL          ;Befehl sichern
  253.         mov     AX,RH.StrtSec   ;Erster Sektor > Diskgr”áe?
  254.         cmp     AX,DiskSz
  255.         ja      RWerr1          ;Ja, Sektorfehler
  256.         mov     XfrSec,AX       ;Ersten Sektor sichern
  257.         mov     BX,RH.SecCnt    ;Anzahl Sektoren sichern
  258.         add     AX,BX           ;letzter Sektor > Diskgr”áe?
  259.         cmp     AX,DiskSz
  260.         ja      RWerr1          ;Ja, Sektorfehler
  261.         mov     XfrCnt,BX       ;Anzahl Sektoren sichern
  262.         les     DI,RH.DTAadr    ;Zeiger fr DTA-Adresse
  263.         mov     XfrAdrO,DI      ;sichern
  264.         mov     XfrAdrS,ES
  265. RW0:    cmp     XfrCnt,0        ;alle Sektoren kopiert ?
  266.         jz      RWEnd           ;Ja, Ende
  267.         mov     AX,XfrSec
  268.         call    MapSec          ;ES:DI ->Sektor
  269.         or      AH,AH
  270.         jnz     RWerr2
  271.         lds     SI,XfrAdr       ;DS:SI ->DOS Buffer(DTA)
  272.         cmp     CS:Cmd,READCMD
  273.         jnz     RW1
  274.         xchg    SI,DI           ;Fr Lese-Befehl,
  275.         push    ES              ;Adressen vertauschen
  276.         push    DS
  277.         pop     ES
  278.         pop     DS
  279. RW1:    mov     CX,SECSZ/2      ;Anzahl Worte
  280.         rep     movsw
  281.         mov     AX,CS           ;DS ->unsere Daten
  282.         mov     DS,AX
  283.         dec     XfrCnt          ;Z„hler - 1
  284.         inc     XfrSec
  285.         add     XfrAdrO,SECSZ
  286.         jmp     RW0             ;n„chsten Sektor
  287. RWerr1: mov     AX,SEC_ERR      ;Expanded-Memory-Fehler
  288.         jmp     RWEnd
  289. RWerr2: mov     AX,CRC_ERR      ;Ungltiger Sektor
  290. RWEnd:  ret
  291.  
  292. ;-----( Ungenutzte Funktionen )-----------------------------
  293. Exit:   mov     AX,CMD_ERR
  294.         ret
  295.  
  296. ;-----( Sektornummer in Speicheradresse umwandeln )---------
  297. ; Eingabe: AX = Sektornummer
  298. ; Ausgabe: ES:DI = -> Sektor
  299. ;          AH <> 0: Fehler
  300. ;-----------------------------------------------------------
  301. MapSec: test    MemTyp,EXPANDED
  302.         jz      MapSec2
  303.         push    AX              ;EMM-Speicher
  304.         mov     CX,5            ;2^5=32 Sektoren/EMM-Seite
  305.         shr     AX,CL           ;AX =EMM-Seite
  306.         cmp     AX,LastPge      ;bereits eingeblendet ?
  307.         je      MapSec1         ;Ja
  308.         mov     LastPge,AX      ;Nein, Seitennummer sichern
  309.         mov     BX,AX           ;logische Seite 'BX' in
  310.         sub     AL,AL           ;physikalische Seite 0
  311.         mov     AH,EMMmapp      ;einblenden
  312.         mov     DX,EMMhdl
  313.         int     EMM
  314.         or      AH,AH
  315.         jnz     MapSecE
  316. MapSec1:pop     DI              ;DI = Sektornummer
  317.         and     DI,01Fh         ;Maske f. unterste 5 Bit
  318.         mov     CX,9
  319.         shl     DI,CL           ;ES:DI -> Segment Adresse
  320.         mov     ES,FrameSeg
  321.         jmp     MapSecE
  322. MapSec2:mov     CX,5            ;2^5=32 Paragraphen
  323.         shl     AX,CL           ;pro 512 Byte Sektor
  324.         add     AX,FrameSeg     ;Segment-Adresse
  325.         mov     ES,AX           ;CX = Segment
  326.         sub     DI,DI           ;BX = 0 = Offset
  327.         sub     AX,AX
  328. MapSecE:ret
  329.  
  330. ;-----( Ende des Treibers )---------------------------------
  331. ; Wenn die RAM-Disk im Hauptspeicher installiert wird, ist
  332. ; dies gleichzeitig der Anfang des Boot-Sektors (Sektor 0
  333. ; der RAM-Disk). Der nachfolgende Code befindet sich inner-
  334. ; halb dieses Sektors. Der Assemblerzeiger wird dazu auf
  335. ; eine runde Paragraphenadresse gesetzt. Beim Einsatz von
  336. ; Expanded Memory, ist dies das Ende des Treibers.
  337. ;-----------------------------------------------------------
  338. DVCLEN  = ($-Main+15)/16        ;Treiberl„nge in Paragraphen
  339.             ORG     DVCLEN*16
  340. BootRec     db  0,0,0           ;Sektor 0 der Disk
  341.             db  'RDISK1.0'      ;8 Byte Bezeichnung
  342. BootBPB     db  BPBlen dup (?)  ;Reservierter fr den BPB
  343. BOOTlen     equ $ - offset BootRec
  344.  
  345. ;----- (Funktion 0: Treiber installieren )------------------
  346. ErrFlag db  0                   ;Flag fr Fehlermeldungen
  347.  
  348. Init:   call    Parse           ;Kommandozeile auswerten
  349.         call    Parms           ;BPB Parameter berechnen
  350.         call    SetUp           ;Speicher reservieren
  351.         call    Format          ;Disk formatieren
  352.         call    SignOn          ;Meldungen ausgeben
  353.         call    FillRH          ;Parameter Rckgabe an DOS
  354.         test    ErrFlag,-1      ;Installationsfehler?
  355.         jnz     InitEnd
  356.                                 ;FAT/Root Sektoren aus temp.
  357.         mov     AX,ResSecs      ;Bereich an ihren end-
  358.         call    MapSec          ;gltigen Platz verschieben.
  359.         mov     AX,32
  360.         mul     NDir            ;Anz. Bytes im Root-Verz.
  361.         mov     CX,AX
  362.         mov     AX,512
  363.         mul     FATsec          ;Anz. Bytes im FAT-Bereich
  364.         add     CX,AX
  365.         push    DS              ;DS hinberretten
  366.         mov     DX,CS           ;Prog.Segment + Prog.l„nge
  367.         add     DX,DRIVERend    ; = Adresse des
  368.         mov     DS,DX           ;tempor„ren Speichers
  369.         sub     SI,SI           ;DS:SI -> temp. FAT/Root
  370.         rep     movsb           ;Daten kopieren
  371.         pop     DS
  372. InitEnd:ret
  373.  
  374. ;-----( "DEVICE="-Zeile  auswerten )------------------------
  375. ; Eingabe: ES:DI = -> Request-Header
  376. ; Ausgabe: DX = Diskgr”áe in KByte
  377. ;-----------------------------------------------------------
  378. Parse:  les     DI,RH.ConfigLn  ;ES:DI -> Text
  379.         sub     DX,DX
  380. ParsNxt:mov     AL,ES:[DI]
  381.         sub     AH,AH
  382.         inc     DI              ;DI -> n„chstes Zeichen
  383.         cmp     AL,CR           ;Zeilenende?
  384.         je      Parse1
  385.         cmp     AL,'/'          ;Optionszeichen ?
  386.         je      Option1
  387.         cmp     AL,'-'          ;altern. Optionszeichen ?
  388.         je      Option1
  389.         mov     CX,AX
  390.         sub     CL,'0'          ;numerisch ?
  391.         jb      ParsNxt         ;Nein
  392.         cmp     CL,9
  393.         ja      ParsNxt         ;Nein
  394.         mov     AX,10
  395.         mul     DX              ;bisheriger Wert * 10
  396.         add     AX,CX           ;neuen Wert hinzuz„hlen
  397.         mov     DX,AX
  398.         jmp     ParsNxt
  399. Option1:mov     AL,ES:[DI]
  400.         inc     DI
  401.         mov     BH,AL
  402.         cmp     BH,'A'          ;Expanded Memory ?
  403.         jne     Option2         ;Nein, weiter
  404.         mov     MemTyp,EXPANDED ;Speicherflag setzen
  405.         jmp     ParsNxt
  406. Option2:cmp     BH,'D'          ;DOS-Speicher
  407.         je      ParsNxt         ;keine weitere Optionen
  408.         or      ErrFlag,OPT_ERR
  409.         jmp     short Parse2
  410. Parse1: cmp     DX,MIN_REQ      ;Mindestgr”áe einstellen
  411.         ja      Parse2
  412.         mov     DX,MIN_REQ
  413. Parse2: test    MemTyp,EXPANDED
  414.         jz      Parse3
  415.         and     DX,NOT 15       ;Auf volle 16kB abrunden
  416.         mov     Npages,DX
  417.         mov     CX,4
  418.         shr     Npages,CL
  419. Parse3: ret
  420.  
  421. ;-----( BPB-Daten berechnen )-------------------------------
  422. ; BPB-Daten berechnen und in den Bootrecord schreiben.
  423. ; Pro 4 KB Diskkapazit„t wird ein Root-Verzeichnis-Eintrag
  424. ; zugelassen (bis max 512). Wir verwenden eine 12-Bit-FAT.
  425. ; Dadurch ist die maximale Anzahl Clusters 0FF7hex(4087).
  426. ; Eingabe: DX = Diskgr”áe in KByte
  427. ; Ausgabe: AX,BX,CX,DX zerst”rt
  428. ;-----------------------------------------------------------
  429. Parms:  mov     DiskSz,DX
  430.         shl     DiskSz,1        ;Anzahl Sektoren
  431.         shr     DX,1            ;Anzahl Verzeichnisse
  432.         shr     DX,1
  433.         cmp     DX,512          ;< 512 ?
  434.         jb      SetDir          ;Ja
  435.         mov     DX,512
  436. SetDir: mov     NDir,DX         ;Anzahl Verzeichnisse
  437.         mov     AX,DiskSz
  438.         mov     CX,2            ;default= 2 Sektoren/Cluster
  439. SetClr: shr     AX,1            ;Anzahl Cluster auf Disk
  440.         cmp     AX,MAXFAT       ;zuviele Clusters ?
  441.         jb      ClrOk           ;Nein
  442.         shl     CX,1            ;Sekt/Cluster verdoppeln
  443.         jmp     SetClr
  444. ClrOk:  mov     ClstrSz,CL      ;Anzahl Clusters pro FAT
  445.         mov     BX,AX           ;AX = Anzahl Clusters
  446.         add     AX,BX           ;AX = 2 * Clusters
  447.         add     AX,BX           ;AX = 3 * Clusters
  448.                                 ;= doppelte FAT L„nge
  449.         add     AX,1023         ;aufrunden
  450.         mov     CX,10           ;           FAT-L„nge
  451.         shr     AX,CL           ;FATsec = -------------
  452.         mov     FATsec,AX       ;         Byte / Sektor
  453.         ret
  454.  
  455. ;-----( Speicher reservieren, RDisk-Adresse berechnen )-----
  456. ; Eingabe: keine
  457. ; Ausgabe: ES = Segmentadresse der "Disk"
  458. ;-----------------------------------------------------------
  459. SetUp:  test    MemTyp,EXPANDED     ;Expanded Memory?
  460.         jz      DMEMsu              ;Nein
  461. EMMsu:  mov     AH,35h              ;EMM vorhanden ?
  462.         mov     AL,EMM              ;Adresse des Int 67h
  463.         int     21h                 ;bestimmen
  464.         mov     DI,0Ah              ;ID-String des EMM
  465.         mov     SI,offset EMMname
  466.         mov     CX,8
  467.         cld
  468.         repz    cmpsb               ;String vergleichen
  469.         jz      EMMsu1
  470.         or      ErrFlag,NoEMM_ERR
  471.         jmp     short SUexit
  472. EMMsu1: mov     AH,EMMframe         ;Segment des EMM-Speichers lesen
  473.         int     EMM
  474.         mov     FrameSeg,BX
  475.         or      AH,AH
  476.         jz      EMMsu2
  477.         or      ErrFlag,EMM_ERR
  478.         jmp     short SUexit
  479. EMMsu2: mov     AH,EMMfree      ;Freien Speicher bestimmen
  480.         int     EMM
  481.         or      AH,AH
  482.         jz      EMMsu3
  483.         or      ErrFlag,EMM_ERR
  484.         jmp     short SUexit
  485. EMMsu3: or      BX,BX           ;Speicher belegt ?
  486.         jnz     EMMsu4          ;Nein
  487.         or      ErrFlag,SZ_ERR
  488. EMMsu4: cmp     Npages,BX       ;Genug Speicher ?
  489.         jbe     EMMsu5
  490.         or      ErrFlag,SZ_ERR
  491.         jmp     short SUexit
  492. EMMsu5: mov     AH,EMMalloc     ;Speicher im EMM reservieren
  493.         mov     BX,Npages       ;BX = Anzahl Seiten
  494.         int     EMM
  495.         mov     EMMhdl,DX       ;Handle sichern
  496.         or      AH,AH
  497.         jz      SUexit
  498.         or      ErrFlag,SZ_ERR
  499.         jmp     SUexit
  500. DMEMsu: mov     AX,CS           ;Speicher berechnen
  501.         add     AX,DVCLEN       ;Ende des Treibers ist zugl.
  502.         mov     FrameSeg,AX     ;Anfang der RAM-Disk
  503.         sub     DX,DX           ;Division vorbereiten
  504.         mov     BX,64           ;Paragraphen/KB
  505.         div     BX
  506.         add     DX,-1           ;auf volle KB aufrunden
  507.         adc     AX,MIN_MEM      ;+ minimaler freier Speicher
  508.         mov     DX,DiskSz       ;= Diskgr”áe in Sektoren
  509.         shr     DX,1            ;/2 = Diskgr”áe in KB
  510.         add     AX,DX           ;Erforderlicher Speicher
  511.         push    AX              ;Wert sichern
  512.         int     12h             ;Speichergr”áe bestimmen
  513.         pop     DX
  514.         sub     AX,DX           ;groá genug ?
  515.         jnc     SUexit          ;Ja
  516.         or      ErrFlag,SZ_ERR  ;Nein, Fehler
  517. SUexit: mov     ES,FrameSeg
  518.         ret
  519.  
  520. ;-----( RAM-Disk "Formatieren" )---------------------------
  521. Format: test    MemTyp,EXPANDED ;Expanded Memory?
  522.         jnz     FrmtEXP         ;Ja
  523.         mov     DX,CS
  524.         add     DX,DRIVERend
  525.         mov     ES,DX
  526.         mov     BX,DiskSz       ;Anzahl Sektoren
  527.         xor     AX,AX
  528. Format1:mov     CX,SECSZ/2      ;Worte/Sektor
  529.         xor     DI,DI
  530.         rep     stosw
  531.         add     DX,SECSZ/16
  532.         mov     ES,DX           ;ES ->n„chsten Sektor
  533.         dec     BX
  534.         jnz     Format1
  535.         jmp     Format5
  536. FrmtEXP:mov     ES,FrameSeg     ;EMM-Fenster Segment
  537.         mov     BX,Npages       ;Anzahl EMM-Seiten
  538. Format2:dec     BX              ;Seite anw„hlen und
  539.         mov     AH,EMMmapp      ;einblenden
  540.         xor     AL,AL
  541.         mov     DX,EMMhdl
  542.         int     EMM
  543.         or      AH,AH           ;Fehler ?
  544.         jnz     FrmtErr         ;Ja!
  545.         mov     CX,2000h        ;Anzahl Worte/EMMseite
  546.         xor     DI,DI
  547.         rep     stosw
  548.         or      BX,BX
  549.         jnz     Format2
  550. Format5:push    DS              ;Bootrecord aufbauen
  551.         pop     ES              ;ES = Datensegment
  552.         mov     DI,offset BootBPB
  553.         mov     SI,offset BPB
  554.         mov     CX,BPBlen
  555.         rep     movsb
  556.         sub     AX,AX           ;Bootrecord kopieren
  557.         call    MapSec          ;ES:DI -> Sektor 0
  558.         mov     SI,offset BootRec
  559.         mov     CX,BOOTlen
  560.         rep     movsb
  561.         mov     DX,CS           ;FAT und Verzeichnis
  562.         add     DX,DRIVERend    ; vorbergehend am Ende
  563.         mov     ES,DX           ; des Programms aufbauen.
  564.         sub     DI,DI           ;ES:DI-> auf FAT
  565.         mov     AL,MEDIA_ID
  566.         stosb                   ;Media Descriptor Byte
  567.         mov     AX,-1           ;...und zwei FFh Byte
  568.         stosw
  569.         mov     AX,512
  570.         mul     FATsec
  571.         sub     AX,3            ; 3 Byte weniger...
  572.         mov     CX,AX           ;   = Z„hler
  573.         sub     AX,AX           ;Rest der FAT l”schen
  574.         rep     stosb           ;DI zeigt jetzt auf Root
  575.         mov     SI,offset VolLabel
  576.         mov     CX,VolLen       ;"Volume Name" ins
  577.         rep     movsb           ;Verzeichnis kopieren
  578.         mov     AX,32
  579.         mul     NDir
  580.         sub     AX,VolLen
  581.         mov     CX,AX           ;CX = Anzahl Bytes im Verz.
  582.         xor     AX,AX           ;Rest des Verzeichnisses
  583.         rep     stosb           ;l”schen
  584.         jmp     short FrmtEnd
  585. FrmtErr:or      ErrFlag,EMM_ERR ;Fehler melden!
  586. FrmtEnd:ret
  587.  
  588. ;------( Daten im Request-Header sichern )------------------
  589. FillRH: mov     AX,CS           ;Gr”áe des Treibers
  590.         add     AX,DVCLEN
  591.         test    MemTyp,EXPANDED
  592.         jnz     FillRH1
  593.         mov     DX,DiskSz       ;Disk ist im Hauptspeicher.
  594.         mov     CX,5            ;Diskgr”áe in Sektoren
  595.         shl     DX,CL           ;* 2^5 Paragr./Sektor
  596.         add     AX,DX
  597. FillRH1:les     DI,ReqHdr       ;Fehler bei Installation ?
  598.         test    ErrFlag,-1
  599.         jnz     FillRH2
  600.         mov     RH.Unum,1       ;Anzahl der Ger„te
  601.         mov     RH.EndOfs,0     ;Programmendeadresse
  602.         mov     RH.EndSeg,AX
  603.         mov     RH.BPBofs, offset BPBptr
  604.         mov     RH.BPBseg,CS    ;Adresse des BPB-Zeigers.
  605.         sub     AX,AX
  606.         ret
  607.  
  608. FillRH2:mov     RH.Unum,0       ;kein Ger„t, kein Speicher!
  609.         mov     RH.EndOfs,0
  610.         mov     RH.EndSeg,CS
  611.         mov     AX,GEN_ERR
  612.         ret
  613.  
  614. ;------( Installation melden )------------------------------
  615. SignOn: @Print  Progname
  616.         test    ErrFlag,SZ_ERR  ;Installationsfehler melden
  617.         jz      SignOn1
  618.         @Print  ErrMess3
  619. SignOnE:@Print  ErrMess0
  620.         ret
  621.  
  622. SignOn1:test    ErrFlag,NoEMM_ERR
  623.         jz      SignOn2
  624.         @Print  ErrMess1
  625.         jmp     SignOnE
  626. SignOn2:test    ErrFlag,EMM_ERR
  627.         jz      SignOn3
  628.         @Print  ErrMess2
  629.         jmp     SignOnE
  630. SignOn3:test    ErrFlag,OPT_ERR
  631.         jz      SignOn4
  632.         @Print  ErrMess4
  633.         jmp     SignOnE
  634. SignOn4:mov     AH,30h          ;DOS-Version ?
  635.         int     21h
  636.         cmp     AL,3            ; 3.xx ?
  637.         jb      SignOn5
  638.         les     DI,ReqHdr
  639.         mov     AL,RH.DrvCode   ;Diskbezeichnung holen
  640.         add     AL,'A'
  641.         mov     Drive,AL
  642. SignOn5:mov     CL,4            ;Reservierte Sektoren:
  643.         mov     AX,NDir
  644.         shr     AX,CL           ; Root-Verzeichnis
  645.         add     AX,FATsec       ; + FAT
  646.         add     AX,2
  647.         and     AX,0FFFEh       ;auf gerade Zahl aufrunden
  648.         mov     DX,DiskSz       ;Diskgr”áe - Res. Sektoren
  649.         sub     DX,AX           ; = Freie Sektoren
  650.         mov     AX,SECSZ        ;* (Byte/Sektor)
  651.         mul     DX              ; = Diskgr”áe in Byte
  652.         mov     SI,offset DiskSize+7
  653.         call    BinAsci         ;in ASCII umwandeln
  654.         mov     AX,NDir         ;Anzahl Verzeichnisse
  655.         cwd                     ;oberes Wort l”schen
  656.         mov     SI,offset DirNum+7
  657.         call    BinAsci
  658.         mov     AX,DiskSz       ;ben”tigter Speicher
  659.         mov     DX,SECSZ
  660.         mul     DX
  661.         mov     SI,offset MemSize+7
  662.         call    BinAsci
  663.         @Print  Mess1           ;Meldungen ausgeben
  664.         @Print  Mess2
  665.         mov     DX,offset DOSmem
  666.         test    MemTyp,EXPANDED
  667.         jz      SignOn6
  668.         mov     DX,offset EXPmem
  669. SignOn6:mov     AH,9
  670.         int     21h
  671.         @Print  Mess3
  672.         ret
  673.  
  674. ;-----( BIN-Zahl in ASCII String umwandeln )----------------
  675. ; Eingabe: DX:AX = 32-Bit-Zahl
  676. ;          DS:SI = -> Ende des String Puffers
  677. ; Ausgabe: DS:SI = -> Anfang des String Puffers
  678. ;-----------------------------------------------------------
  679. BinAsci:xor     BP,BP
  680.         xchg    BP,DX           ;BP = oberes Wort
  681.         mov     CX,10           ;CX = Teiler
  682. BAloop: xchg    AX,BP           ;oberes Wort holen
  683.         xor     DX,DX           ;Ergebnis l”schen
  684.         div     CX
  685.         xchg    AX,BP           ;unteres Wort holen
  686.         div     CX
  687.         or      DL,'0'          ;in ASCII-Zahl umwandeln
  688.         mov     [SI],DL         ;and drop at target
  689.         dec     SI              ;set up for next character
  690.         or      AX,AX           ;noch was zu tun?
  691.         jnz     BAloop          ;Ja, weiter
  692.         ret
  693.  
  694. ;-----( Transienter Datenbereich )--------------------------
  695. EMMname     db  'EMMXXXX0'     ;Bezeichnung des EMM-Handlers
  696. VolLabel    db  'RDISK V:1.0'  ;"Volume" Name: 11 Bytes
  697.             db  28h            ;Volume Attribut
  698.             dt  0              ;10 reservierte Bytes
  699.             dw  24576          ;12:00 Uhr
  700.             dw  4865           ;1.August.1989
  701.             db  6 dup (0)      ;6 reservierte Bytes
  702. VolLen      =   $ - VolLabel   ;L„nge
  703. Mess1       db  'RAM-Disk '
  704. Drive       db  '$: $'
  705. Mess2       db  'erfolgreich installiert.',CR,LF
  706. DiskSize    db  '         Bytes verfgbar.',CR,LF
  707. DirNum      db  '         Verzeichnisse im ¯Root®.',CR,LF
  708. MemSize     db  '         Bytes $'
  709. DOSmem      db  'DOS-Speicher $'
  710. EXPmem      db  'Expanded Memory $'
  711. Mess3       db  'wurden verwendet.',CR,LF,'$'
  712. ErrMess1    db  'Kein Expanded Memory vorhanden',CR,LF,'$'
  713. ErrMess2    db  'Fehler im EMM-Treiber',CR,LF,'$'
  714. ErrMess3    db  'Zu wenig Speicher frei',CR,LF,'$'
  715. ErrMess4    db  'Unbekannte Option',CR,LF,'$'
  716. ErrMess0    db  'RAM-Disk NICHT installiert.',CR,LF,BEEP,'$'
  717.  
  718. ;-----( Programmende )--------------------------------------
  719. DRIVERend   =   ($-Main+15)/16    ;Prog.L„nge in Paragraphen
  720. CODE        ends
  721. END         Main
  722.